/**
 * 普通基环树，一共有N条边，for i in [1, N]:
 *    问删掉第i条边，节点1到N的最短距离是多少
 * 
 * 首先求环，直接套了点双的模板，将环上的边保存在H中。
 * 然后用广搜求出1到N的最短距离，O(N)即可。用Dij超时了。
 * 并且确定构成最短路径的边，记作Road，并且求出该最短路有多少条边在环上。
 * 
 * 对每一条边i，如果不在Road中，则距离不变。
 * 如果边i不在环上，则1、N变为不连通，
 * 否则路径变为走环的另一边，可以很容易计算出这条路径的长度。
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using vi = vector<int>;

struct VCCTarjan{ // 点双连通分量

using weight_t = int;
using vi = vector<int>;

struct edge_t{
    int from;
    int to;
    weight_t w;
    edge_t(int a, int b, weight_t c):from(a),to(b),w(c){}
};

int N;
vector<edge_t> Edges;
vector<vi> G; // 编号从1开始

/// 点数和边数
void init(int n, int m){
    G.assign((N = n) + 1, {});
    Edges.clear();
    Edges.reserve(m + m); // 无向边
    return;
}

/// 双向边
void mkBiEdge(int a, int b, weight_t w=0){
    G[a].emplace_back(Edges.size());
    Edges.emplace_back(a, b, w);
    G[b].emplace_back(Edges.size());
    Edges.emplace_back(b, a, w);
    return;
}

/// 主函数
void Tarjan(){
    /// 初始化
    Dfn.assign(N + 1, 0);
    Low.assign(N + 1, 0);
    Stack.assign(Edges.size(), 0);
    Belong2VCC.assign(Edges.size(), 0);
    IsVisited.assign(Edges.size(), 0);
    Represent.assign(Edges.size(), 0);
    TimeStamp = VCCCnt = StackTop = 0;

    for(int i=1;i<=N;++i)if(0 == Dfn[i])dfs(i, i);
    return;
}

void dfs(int u, int pre){
    Dfn[u] = Low[u] = ++TimeStamp;

    int v, j;
    for(auto i : G[u])if(not IsVisited[i]){
        IsVisited[i] = IsVisited[i ^ 1] = true;

        if(0 == Dfn[v = Edges[i].to]){ // 入栈
            Stack[StackTop++] = i;
            dfs(v, u);
            if(Low[v] < Low[u]) Low[u] = Low[v];

            /// 说明u是割点，栈内的边属于同一个点双
            if(Dfn[u] <= Low[v]){
                Represent[Belong2VCC[i] = Belong2VCC[i ^ 1] = ++VCCCnt] = i;
                while((j = Stack[--StackTop]) != i){
                    Belong2VCC[j] = Belong2VCC[j ^ 1] = VCCCnt;
                    Represent[VCCCnt] = min(j, Represent[VCCCnt]);
                }
            }
        }else if(v != pre and Dfn[v] < Dfn[u]){
            Low[u] = min(Low[u], Dfn[v]);
            Stack[StackTop++] = i;
        }
    }
}

int StackTop;
vi Stack; // 辅助栈
int TimeStamp;
vi Dfn, Low;
/// 对点而言，割点可能属于多个点双连通分量
/// 编号使用的是内部编号
/// 实际读入边的顺序记作1,2,3,...，分别对应内部编号(0,1)(2,3)(4,5)...
vi Belong2VCC; // 边i属于第Bi个点双连通分量，从1开始
vi Represent; // Ri表示第i个点双中最小的边的编号
int VCCCnt; // 点双的数量
vi IsVisited;

}T;



int N, M;
vector<int> Sz;
set<int> H;
set<int> Road;

vector<int> Pre;

int bfs(){
    static int const INF = 1E6;
    vi flag(N + 1, 0);
    vi D(N + 1, INF);
    Pre.assign(N + 1, 0);

    queue<int> Q;
    Q.push(1);
    D[1] = 0;
    
    int sz = 0;
    while(sz = Q.size()){
        while(sz--){
            auto h = Q.front();Q.pop();
            for(auto i : T.G[h]){
                int v = T.Edges[i].to;
                if(D[v] != INF) continue;

                D[v] = D[h] + 1;
                Pre[v] = i;
                Q.push(v);
            }
        }
    }

    return D[N];
}

void work(){
    cin >> N;
    T.init(N, N);
    for(int a,b,i=0;i<N;++i){
        cin >> a >> b;
        T.mkBiEdge(a, b);
    }
    T.Tarjan();

    Sz.assign(T.VCCCnt + 1, 0);
    for(int i=0;i<T.Edges.size();i+=2){
        ++Sz[T.Belong2VCC[i]];
    }

    int hidx = 0;
    int hsize = 0;
    for(int i=1;i<=T.VCCCnt;++i){
        if(Sz[i] > 1){
            assert(0 == hidx);
            hsize = Sz[hidx = i];
        }
    }

    for(int i=0;i<T.Edges.size();i+=2){
        if(T.Belong2VCC[i] == hidx){
            H.insert(i / 2 + 1);
        }        
    }

    int dis = bfs();
    int acrossHuan = 0;
    for(int i=N;i!=1;i=T.Edges[Pre[i]].from){
        Road.insert(Pre[i] / 2 + 1);
        auto it = H.find(Pre[i] / 2 + 1);
        if(it != H.end()) ++acrossHuan;
    }

    for(int i=1;i<=N;++i){
        auto it = Road.find(i);
        if(it == Road.end()){
            cout << dis << "\n";
        }else{
            auto jt = H.find(i);
            if(jt == H.end()) {
                cout << "-1\n";
            }else{
                cout << dis - acrossHuan + (hsize - acrossHuan) << "\n";
            } 
        }
    }
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}